package graph;

import java.util.*;

/**
 * 拓扑排序
 * 117. 软件构建
 * 题目描述
 * 某个大型软件项目的构建系统拥有 N 个文件，文件编号从 0 到 N - 1，在这些文件中，某些文件依赖于其他文件的内容，这意味着如果文件 A 依赖于文件 B，则必须在处理文件 A 之前处理文件 B （0 <= A, B <= N - 1）。请编写一个算法，用于确定文件处理的顺序。
 * 输入描述
 * 第一行输入两个正整数 N, M。表示 N 个文件之间拥有 M 条依赖关系。
 * 后续 M 行，每行两个正整数 S 和 T，表示 T 文件依赖于 S 文件。  s->T
 * 输出描述
 * 输出共一行，如果能处理成功，则输出文件顺序，用空格隔开。
 * 如果不能成功处理（相互依赖），则输出 -1。
 *
 * 1.找到入度为 0 的节点，加入结果集
 * 2.将该节点从图中移除
 * 3.更新每个节点的入度
 */

/**
 * 一刷二刷一样
 */
public class buildsoftware {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        List<List<Integer>> umap = new ArrayList<>();
        int[] indgree = new int[n + 1];
        for (int i = 0; i < n; i++)
            umap.add(new ArrayList<>());


        for (int i = 0; i < m; i++) {
            int s = sc.nextInt();
            int t = sc.nextInt();
            umap.get(s).add(t);
            indgree[t]++;
        }

        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            if (indgree[i] == 0) {
                // 入度为0的文件，可以作为开头，先加入队列
                queue.add(i);
            }
        }
        List<Integer> result = new ArrayList<>();

        while (!queue.isEmpty()) {
            int cur = queue.poll(); // 当前选中的文件
            result.add(cur);
            for (int file : umap.get(cur)) {
                indgree[file]--; // cur的指向的文件入度-1
                if (indgree[file] == 0) {
                    queue.add(file);
                }
            }
        }

        if (result.size() == n) {
            for (int i = 0; i < n - 1; i++) {
                System.out.print(result.get(i) + " ");
            }
            System.out.print(result.get(n - 1));
        } else
            System.out.println(-1);


    }
}
